/*
 * Created on 2004-12-22
 */
package org.nanhill.commons.lang;

/**
 * @author wang lin
 */
public class ArrayKit {
	/** 空的<code>Object</code>数组。 */
	public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];

	/** 空的<code>Class</code>数组。 */
	public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];

	/** 空的<code>String</code>数组。 */
	public static final String[] EMPTY_STRING_ARRAY = new String[0];

	/** 空的<code>long</code>数组。 */
	public static final long[] EMPTY_LONG_ARRAY = new long[0];

	/** 空的<code>Long</code>数组。 */
	public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0];

	/** 空的<code>int</code>数组。 */
	public static final int[] EMPTY_INT_ARRAY = new int[0];

	/** 空的<code>Integer</code>数组。 */
	public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];

	/** 空的<code>short</code>数组。 */
	public static final short[] EMPTY_SHORT_ARRAY = new short[0];

	/** 空的<code>Short</code>数组。 */
	public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0];

	/** 空的<code>byte</code>数组。 */
	public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];

	/** 空的<code>Byte</code>数组。 */
	public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0];

	/** 空的<code>double</code>数组。 */
	public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];

	/** 空的<code>Double</code>数组。 */
	public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0];

	/** 空的<code>float</code>数组。 */
	public static final float[] EMPTY_FLOAT_ARRAY = new float[0];

	/** 空的<code>Float</code>数组。 */
	public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0];

	/** 空的<code>boolean</code>数组。 */
	public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];

	/** 空的<code>Boolean</code>数组。 */
	public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0];

	/** 空的<code>char</code>数组。 */
	public static final char[] EMPTY_CHAR_ARRAY = new char[0];

	/** 空的<code>Character</code>数组。 */
	public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];

	public static void copyAll(Object[] src, Object[] des, int destPos) {
		System.arraycopy(src, 0, des, destPos, src.length);
	}

	public static void copyAll(Object[] des, int destPos, Object[]... srcs) {
		for (int i = 0; i < srcs.length; i++) {
			int len = srcs[i].length;
			System.arraycopy(srcs[i], 0, des, destPos, len);
			destPos += len;
		}
	}

	public static void copyAll(int[] src, int[] des, int destPos) {
		System.arraycopy(src, 0, des, destPos, src.length);
	}

	public static void printlnStringArray(String[] in) {
		for (int i = 0; i < in.length; i++) {
			System.out.println(in[i]);
		}
	}

	public static int binarySearch(int[] a, int key) {
		int low = 0;
		int high = a.length - 1;

		while (low <= high) {
			int mid = (low + high) >> 1;
			int midVal = a[mid];

			if (midVal < key)
				low = mid + 1;
			else if (midVal > key)
				high = mid - 1;
			else
				return mid; // key found
		}
		return -(low + 1); // key not found.
	}

	private static final int NegaOne = -1;

	private static final int NegaTwo = -2;

	/**
	 * Compare two obejct array, return -1 if they are equals, all null or all
	 * empty, return other negative if one of them is null or empty, else return
	 * the position of first not equals element.
	 * 
	 * @param src
	 * @param des
	 * @return
	 */
	public static int compare(Object[] src, Object[] des) {
		int pos = NegaTwo;
		if (null == src) {
			return null == des ? NegaOne : pos;
		}
		if (null == des) {
			return pos;
		}
		if (src.length == 0) {
			return 0 == des.length ? NegaOne : pos;
		}
		if (des.length == 0) {
			return pos;
		}
		for (int i = 0; i < src.length; i++) {
			Object item = src[i];
			if (null == item && null != item) {
				return i;
			}
			if (!item.equals(des[i])) {
				return i;
			}
		}
		return NegaOne;
	}

	/**
	 * Compare two integer array, return -1 if they are equals, all null or all
	 * empty, return other negative if one of them is null or empty, else return
	 * the position of first not equals element.
	 * 
	 * @param src
	 * @param des
	 * @return
	 */
	public static int compare(int[] src, int[] des) {
		int pos = NegaTwo;
		if (null == src) {
			return null == des ? NegaOne : pos;
		}
		if (null == des) {
			return pos;
		}
		if (src.length == 0) {
			return 0 == des.length ? NegaOne : pos;
		}
		if (des.length == 0) {
			return pos;
		}
		for (int i = 0; i < src.length; i++) {
			if (src[i] != des[i]) {
				return i;
			}
		}
		return NegaOne;
	}

	public static String toString(Object[] a, String join) {
		if (a == null)
			return "null";
		if (a.length == 0)
			return "[]";

		StringBuilder buf = new StringBuilder();

		for (int i = 0; i < a.length; i++) {
			if (i == 0)
				buf.append('[');
			else
				buf.append(join);

			buf.append(String.valueOf(a[i]));
		}

		buf.append("]");
		return buf.toString();
	}

	public static String toString(Object[] a, StringProcessor ps) {
		if (a == null)
			return "null";
		if (a.length == 0)
			return "[]";

		StringBuilder buf = new StringBuilder();

		for (int i = 0; i < a.length; i++) {
			if (i == 0)
				buf.append('[');
			buf.append(ps.process(String.valueOf(a[i])));
		}

		buf.append("]");
		return buf.toString();
	}

	public static String join(Object[] a, char join) {
		if (a == null || a.length == 0)
			return StringConstants.EMPTY;
		StringBuilder buf = new StringBuilder();
		for (int i = 0; i < a.length; i++) {
			if (i != 0)
				buf.append(join);
			buf.append(String.valueOf(a[i]));
		}
		return buf.toString();
	}

	public static boolean isEmpty(Object[] arr) {
		return arr == null ? true : arr.length == 0;
	}

	@SuppressWarnings("unchecked")
	public static Object[] trim(Object[] arr) {
		Object[] tmp = new Object[arr.length];
		int j = 0;
		for (int i = 0; i < arr.length; i++) {
			Object now = arr[i];
			if (now != null) {
				tmp[j++] = now;
			}
		}
		Object[] des = new Object[j];
		if (j != 0) {
			System.arraycopy(tmp, 0, des, 0, des.length);
		}
		return des;
	}

	public static String[] trim(String[] arr) {
		String[] tmp = new String[arr.length];
		int j = 0;
		for (int i = 0; i < arr.length; i++) {
			String now = arr[i];
			if (now != null) {
				tmp[j++] = now;
			}
		}
		String[] des = new String[j];
		if (j != 0) {
			System.arraycopy(tmp, 0, des, 0, des.length);
		}
		return des;
	}
}